package com.localjoycommunity.cpdj.common.interceptor;

import com.alibaba.fastjson.JSON;
import com.localjoycommunity.cpdj.common.CodeMsg;
import com.localjoycommunity.cpdj.common.R;
import com.localjoycommunity.cpdj.common.constant.Constants;
import com.localjoycommunity.cpdj.common.interceptor.help.NeedLogin;
import com.localjoycommunity.cpdj.common.interceptor.help.UserContext;
import com.localjoycommunity.cpdj.framework.redis.RedisCache;
import com.localjoycommunity.cpdj.project.system.domain.User;
import com.localjoycommunity.cpdj.project.system.domain.vo.WeixinVO;
import com.localjoycommunity.cpdj.project.system.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;

/**
 * @Function:
 * @Author: aqie
 * @Date: 2019/4/20 14:35
 */
@Service
@Slf4j
public class AccessInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    IUserService userService;

    @Autowired
    private RedisCache redisCache;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            User user = null;
            String sessionKey = request.getHeader(Constants.SESSION_KEY);
            if (StringUtils.isNotBlank(sessionKey)) {
                user = getUser(sessionKey);
                UserContext.setToken(sessionKey);
            }

            HandlerMethod handlerMethod = (HandlerMethod) handler;
            NeedLogin needLoginAnnotation = handlerMethod.getMethodAnnotation(NeedLogin.class);
            if (needLoginAnnotation == null) {
                return true;
            }
            boolean needLogin = needLoginAnnotation.needLogin();

            if (needLogin) {
                if (user == null) {
                    render(response, CodeMsg.TOKEN_INVALID_ERROR);
                    return false;
                }
            }
            // todo redis计数 进行接口限流

        }
        return true;
    }

    private void render(HttpServletResponse response, CodeMsg codeMsg) throws Exception {
        response.setContentType("application/json;charset=UTF-8");
        OutputStream out = response.getOutputStream();
        String str = JSON.toJSONString(R.error(codeMsg));
        out.write(str.getBytes(StandardCharsets.UTF_8));
        out.flush();
        out.close();
    }

    /**
     * 根据 session_key 从缓存获取用户
     * @return
     */
    private User getUser(String sessionKey) {
        WeixinVO weixinVO = redisCache.getCacheObject(sessionKey);
        if (weixinVO == null) {
            return null;
        }
        return weixinVO.getUser();
    }


    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
                                Object handler, Exception ex) throws Exception {
        super.afterCompletion(request, response, handler, ex);
        UserContext.removeUser();
    }
}
